/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
 H    process.h
 H    Application name:  tcss422-project2
 H    Programmers names:  Evan Phillips, Lucas Cowell, Tony Butterfield
 H    Date created:  May 9, 2011
 H    Date completed:
 H    Brief Description:  A simulation of a process that generates interrupts.
 H
 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/


#ifndef PROCESS_H_
#define PROCESS_H_
#endif /* PROCESS_H_ */


/* FORWARD DEFINITIONS - resolves circular dependencies */
struct process_queue_str;       // forward definition of a process queue
struct semaphore_str;			//forward definition of semaphore struct

/***************************************************************************************************
 *  ADT: Process
 *  Description:  In an actual multi-threaded version of this project, a process would be an actual
 *          thread that would loop through a count, sending simulated system requests at preset
 *          ticks and being told to sleep when blocked.
 *
 *          In this single-threaded version, the main process will have to simulate the actions of
 *          an independent process thread, looping through its steps and setting its state, so I've
 *          implemented it as a simple struct with the number of steps, and an array of
 *          step number-system request pairs that have to be checked on each process tick.
 *
 *          The sequence of requests should be predefined (in main.h) for different process types
 *          (consumer, producer, calculation, etc.) and passed to the Process when it's initialized.
 *
 *          The Process Control Block is also embedded in the process struct with getters and
 *          setters for the Scheduler to use.
 *
 *  Implementation:  a struct containing the number of steps and an array of requests to be
 *          generated.  Each process has a Program Control Block that stores its state when
 *          interrupted with appropriate setters and getters
 *
 ***************************************************************************************************/

/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 $ Typedefs
 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
typedef struct request_type_str // typedefs for Request
{
        int step_number;        // step number trigger
        int request_type;       // the type of request
}RequestTypeStr;
typedef RequestTypeStr* Request;

typedef struct pcb_str          // typedefs for process control block
{
        int pid;                                // the process id
        char* name;                             // process name
        int next_step;                          // the step that was 'interrupted'
        int state;                              // P_RUNNING, P_READY, P_INTERRUPTED, P_BLOCKED
        struct process_queue_str* waiting_on;   // object owning the queue its waiting in
        struct semaphore_str* owns;         // semaphore this process owns.
}pcbStr;
typedef pcbStr* PCB;

typedef struct process_str      // typedefs for Process
{
        PCB pcb;                // process control block.
        int num_steps;          // number of 'instructions' to be executed by this process.
        int num_requests;       // number of interrupts to be thrown (size of the request array?)
        Request* requests;      // array of Requests (step number + request types)
}processStr;
typedef processStr* Process;


/*-------------------------------------------------------------------------------------------------
 - Prototypes -
 -      Initialize - creates an Process with a given number of steps and array of requests.
 -      Terminate - deallocates memory for PCB, array of Requests, and the Process itself.
 -
 -      Set PID - process ID assigned by scheduler.
 -      Get PID - return process ID
 -      Set next step - set number of interrupted step.
 -      Get next step - get number of interrupted step.
 -      Set state - set process' current state.
 -      Get state - get current state.
 -      Set waiting_on - set pointer to the blocking queue (alt name: thatsTheHoldup(). ;)
 -      Get waiting_on - get pointer to the blocking queue.(alt name: whatsTheHoldup(). ;)
 -      Set owns - set pointer to the semaphore owned by this process
 -      Get owns - get pointer to the semaphore owned.
 -
 ---------------------------------------------------------------------------------------------------*/

Process     p_init(int, char*, int, int);   // new Process
PCB         pcb_init(int, char*);
int         p_free(Process);                // deallocate memory used by Process

int         p_setPID(Process, int);         // sets the PID field of the process' PCB
int         p_getPID(Process, int*);        // get the PID from the PCB

int         p_setNextStep(Process, int);    // set the interrupted step in the PCB.
int         p_getNextStep(Process, int*);   // get the interrupted step from the process' PCB.

int         p_setState(Process, int);       // set process' current state
int         p_getState(Process, int*);      // get process' current state

int         p_setWaiting(Process, struct process_queue_str*);   // set pointer to blocking q
int         p_setOwns(Process, struct semaphore_str*);  // set pointer to the semaphore owned

struct process_queue_str*   p_getWaiting(Process, int*);
struct semaphore_str*   p_getOwns(Process, int*);       // get pointer to the semaphore owned

BOOLEAN     p_isRequest(Process, int, int*);    // returns true if there is a request at given step number
int         p_getRequest(Process, int, int*);   // returns the Request code at the given step number


Request* 	req_init(int, int*);            // initializes a request array of size int




